home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_1 / fraction < prev    next >
Internet Message Format  |  1995-03-31  |  14KB

  1. From hpcvbbs!davev Tue Jun  5 08:46 PDT 1990
  2. Received: from hpcvra.HP.COM by hpcvrz.HP.COM; Tue, 5 Jun 90 08:46:23 pdt
  3. Received: by hpcvra.HP.COM; Tue, 5 Jun 90 08:46:37 pdt
  4. Received: from hpcvbbs with uucp; Tue, 5 Jun 90 08:39:38
  5. Received: by hpcvbbs.HP.COM; Tue, 5 Jun 90 08:39:38 pdt
  6. Date: Tue, 5 Jun 90 08:39:38 pdt
  7. From: Dave Vomocil <hpcvbbs!davev>
  8. Message-Id: <9006051539.AA27810@hpcvbbs.HP.COM>
  9. To: hpcvbbs!davev
  10. Subject: frac.doc
  11. Status: R
  12.  
  13.  
  14.  
  15. ~% The attached programs can be used to turn your HP48SX into a four
  16. function RPN machine that handles fractions graphically.  That is,
  17. you will be able perform computations on mixed numbers the way you did
  18. in grade school.  The pieces (i.e. files/programs) you need are:
  19.  
  20. ~% GCD  computes greatest common divisor
  21. ~% LCM  computes least common multiple
  22.  
  23. ~% (you should be getting a feeling of nostalgia by now :-)
  24.  
  25. ~% PLUS~ used to add two mixed numbers
  26. ~% SUBTR  used to subtract two mixed numbers
  27. ~% MULTI  used to multiply two mixed numbers
  28. ~% DIVI~ used to divide two mixed numbers
  29. ~% DPLAY  used to display a mixed number
  30. ~% SWAPR  used to 'swap' two mixed numbers on the stack
  31. ~% DISPL  common display code used by DPLAY, PLUS, SUBTR, etc.
  32. ~% ADD~$ common arithmetic code used by PLUS and SUBTR.
  33.  
  34. ~% KEYS~ this is a list you can hand to STOK to assign values
  35. ~, to your 'user' keys.
  36.  
  37. How to get your calculator set up:
  38. ~% Download the attached item to your PC and then on to your 48SX.
  39. ~% You should get the 48 item FRAC.  Recall it to your stack.
  40. ~% Get to your HOME directory.  Press EVAL.
  41.  
  42. ~% This will create the above list of items in your home directory,
  43. ~% and it will assign user values to the '+', '-', '*', '/', 
  44. ~% <left shift> <review>, and <swap> user keys.  If you have existing
  45. ~% values assigned to these keys, they will get clobbered.  Of you
  46. ~% have items in your HOME directory with conflicting names, they
  47. ~% will get clobbered.
  48.  
  49. ~% You should place these items in your home directory so you will
  50. ~% always have access to them.
  51.  
  52. ~% <left shift> <usr> <left shift> <usr> to activate your user key
  53. ~% assignments.
  54.  
  55. How to do fractions:
  56. ~% The software looks to the stack for arguments.  It uses three levels
  57. ~% to define a mixed number.  It wants the whole number in level three,
  58. ~% the numerator in level two, and the denominator in level one.  
  59.  
  60. ~% The operators '+', '-', '*', '/' and 'swap' expect two mixed numbers 
  61. ~% on the stack.  The arithmetic operators leave only the result on the
  62. ~% stack.
  63.  
  64. ~% The <left shift> <review> operator displays the mixed number in 
  65. ~% levels 1, 2, & 3; and leaves it the stack unchanged.
  66.  
  67. Example:
  68.  
  69. ~% Press:  1 <spc> 2 <spc> 3 <enter> <left shift> <review>
  70.  
  71. ~% And see one and two thirds displayed.
  72.  
  73. ~% Then press 4 <spc> 5 <spc> 6 +
  74.  
  75. ~% And see one and two thirds plus four and five sixths equals
  76. ~% six and one half.
  77.  
  78. Bugs:
  79. ~% The whole number must be positive.  The software does not handle
  80. ~% a negative mixed number correctly.  For example, it says six and
  81. ~% one half plus a negative three and on half equals four.
  82.  
  83. ~1. dave vomocil
  84.  
  85.  
  86. %%HP: T(3)A(D)F(.);
  87.  
  88. \<< 
  89.  
  90. @ Each mixed number is a list of size three.
  91. 3 \->LIST 4 ROLLD 3 \->LIST SWAP
  92.  
  93. @ Check that both denom's are non-zero.
  94. DUP2 3 GET SWAP 3 GET AND IF NOT 
  95. THEN
  96.    440 .5 BEEP
  97.    "PLUS: zero in denom" 1 DISP 1 FREEZE
  98. ELSE
  99.  
  100.     64 R\->B 131 R\->B BLANK PICT STO  @ Blank a 64X131 PICT
  101.  
  102.     @ Display the first addend
  103.     SWAP 0 DISPL SWAP 
  104.  
  105.     @ Now figure out where to place the + sign
  106.     1 GETI SWAP DROP \->STR SIZE 2 + 6 * NEG 65 + R\->B
  107.     20 R\->B 2 \->LIST PICT SWAP
  108.     " + " 3 \->GROB                         @ GOR the + sign into PICT
  109.     GOR
  110.  
  111.     @ And now the second addend
  112.     15 DISPL
  113.     25 R\->B 30 R\->B 2 \->LIST
  114.     85 R\->B 30 R\->B 2 \->LIST LINE
  115.  
  116.     @ ADD the two mixed numbers and DISPL the sum.
  117.  
  118.     @ Compute LCM of denominators
  119.     DUP 3 GET 3 ROLL DUP 3 GET 3 ROLL LCM 0 DUP \-> lcm numer carry
  120.     \<<
  121.  
  122.     @ Compute numerator of fraction 1
  123.     2 GETI 3 ROLLD GETI SWAP DROP 
  124.     lcm SWAP / 3 ROLL * 'numer' STO
  125.  
  126.     @ Compute numerator of fraction 2 and add
  127.     SWAP 2 GETI 3 ROLLD GETI SWAP DROP 
  128.     lcm SWAP / 3 ROLL * numer + 'numer' STO
  129.  
  130.     @ Check for carry and reduce fraction part
  131.     numer lcm / IP 'carry' STO
  132.     numer lcm MOD 'numer' STO
  133.     numer lcm GCD  DUP
  134.  
  135.     @ Reduce if non-zero GCD
  136.     DUP IF THEN
  137.          numer SWAP / 'numer' STO
  138.          lcm SWAP / 'lcm' STO
  139.        ELSE
  140.          DROP2
  141.        END
  142.  
  143.     @ Add the whole numbers and the carry
  144.     1 GET SWAP 1 GET + carry +
  145.  
  146.     @ Form the mixed number list
  147.     numer lcm 3 \->LIST
  148.  
  149.     \>> @ end of scope of lcm numer and carry
  150.  
  151.     @ DISPL the result
  152.     32 DISPL
  153.  
  154. @ Convert the list to elements on the stack.
  155. OBJ\-> DROP
  156.  
  157. END
  158. \>> 'PLUS' STO
  159.  
  160.  
  161. \<< 
  162.  
  163. @ Convert elements on the stack to two lists
  164. 3 \->LIST 4 ROLLD 3 \->LIST SWAP
  165.  
  166. @ Check that both denom's are non-zero.
  167. DUP2 3 GET SWAP 3 GET AND IF NOT 
  168. THEN
  169.    440 .5 BEEP
  170.    "SUBTR: zero in denom" 1 DISP 1 FREEZE
  171. ELSE
  172.  
  173.     64 R\->B 131 R\->B BLANK PICT STO  @ Blank a 64X131 PICT
  174.  
  175.     @ Display the first minuend
  176.     SWAP 0 DISPL SWAP 
  177.  
  178.     @ Now figure out where to place the - sign
  179.     1 GETI SWAP DROP \->STR SIZE 2 + 6 * NEG 65 + R\->B
  180.     20 R\->B 2 \->LIST PICT SWAP
  181.     " - " 3 \->GROB                         @ GOR the + sign into PICT
  182.     GOR
  183.  
  184.     @ And now the second subtrahend
  185.     15 DISPL
  186.     25 R\->B 30 R\->B 2 \->LIST
  187.     85 R\->B 30 R\->B 2 \->LIST LINE
  188.  
  189.     @ ADD the two mixed numbers and DISPL the sum.
  190.  
  191.     @ Compute LCM of denominators
  192.     DUP 3 GET 3 ROLL DUP 3 GET 3 ROLL LCM 0 DUP \-> lcm numer borrow
  193.     \<<
  194.  
  195.     @ Compute numerator of fraction 1
  196.     2 GETI 3 ROLLD GETI SWAP DROP 
  197.     lcm SWAP / 3 ROLL * 'numer' STO
  198.  
  199.     @ Compute numerator of fraction 2 
  200.     SWAP 2 GETI 3 ROLLD GETI SWAP DROP 
  201.     lcm SWAP / 3 ROLL *  numer SWAP - DUP
  202.  
  203.     @ Determine if we need to borrow
  204.     WHILE 0 < 
  205.        REPEAT lcm + DUP 'borrow' 1 STO+ END
  206.     'numer' STO
  207.  
  208.     @ Reduce fraction part
  209.     numer lcm GCD  DUP
  210.    
  211.     @ Reduce if non-zero GCD
  212.     DUP IF THEN
  213.          numer SWAP / 'numer' STO
  214.          lcm SWAP / 'lcm' STO
  215.        ELSE
  216.          DROP2
  217.        END
  218.  
  219.     @ Subtract the whole numbers 
  220.     SWAP 1 GET SWAP 1 GET - borrow -
  221.  
  222.     @ Form the mixed number list
  223.     numer lcm 3 \->LIST
  224.  
  225.     \>> @ end of scope of lcm numer and carry
  226.  
  227.     @ DISPL the result
  228.     32 DISPL
  229.  
  230. @ Convert the list to elements on the stack
  231. OBJ\-> DROP
  232.  
  233. END 
  234. \>> 'SUBTR' STO
  235.  
  236. \<< 
  237.  
  238. @ Compute LCM of denominators
  239. DUP 3 GET 3 ROLL DUP 3 GET 3 ROLL LCM 0 DUP \-> lcm numer carry
  240. \<<
  241.  
  242. @ Compute numerator of fraction 1
  243. 2 GETI 3 ROLLD GETI SWAP DROP 
  244. lcm SWAP / 3 ROLL * 'numer' STO
  245.  
  246. @ Compute numerator of fraction 2 and add
  247. SWAP 2 GETI 3 ROLLD GETI SWAP DROP 
  248. lcm SWAP / 3 ROLL * numer + 'numer' STO
  249.  
  250. @ Check for carry and reduce fraction part
  251. numer lcm / IP 'carry' STO
  252. numer lcm MOD 'numer' STO
  253. numer lcm GCD  DUP
  254.  
  255. @ Reduce if non-zero GCD
  256. DUP IF THEN
  257.          numer SWAP / 'numer' STO
  258.          lcm SWAP / 'lcm' STO
  259.        ELSE
  260.      DROP2
  261.        END
  262.  
  263. @ Add the whole numbers and the carry
  264. 1 GET SWAP 1 GET + carry +
  265.  
  266. @ Form the mixed number list
  267. numer lcm 3 \->LIST
  268.  
  269. \>> @ end of scope of lcm numer and carry
  270. \>> 'ADD' STO
  271.  
  272. \<< 
  273.  
  274. @ Convert the elements on the stack to two lists.
  275. 3 \->LIST 4 ROLLD 3 \->LIST SWAP
  276.  
  277. @ Check that both denom's are non-zero.
  278. DUP2 3 GET SWAP 3 GET AND IF NOT 
  279. THEN
  280.    440 .5 BEEP
  281.    "SUBTR: zero in denom" 1 DISP 1 FREEZE
  282. ELSE
  283.  
  284.     64 R\->B 131 R\->B BLANK PICT STO  @ Blank a 64X131 PICT
  285.  
  286.     @ Display the first mmultiplier
  287.     SWAP 0 DISPL SWAP 
  288.  
  289.     @ Now figure out where to place the * sign
  290.     1 GETI SWAP DROP \->STR SIZE 2 + 6 * NEG 65 + R\->B
  291.     20 R\->B 2 \->LIST PICT SWAP
  292.     " * " 3 \->GROB                         @ GOR the + sign into PICT
  293.     GOR
  294.  
  295.     @ And now the second multiplier
  296.     15 DISPL
  297.     25 R\->B 30 R\->B 2 \->LIST
  298.     85 R\->B 30 R\->B 2 \->LIST LINE
  299.  
  300.     @ Multiply the two mixed numbers and DISPL the sum.
  301.  
  302.     @ Convert the two mixed numbers to improper fractions.
  303.     3 GETI 3 ROLLD GETI 4 ROLL * 3 ROLLD GETI 4 ROLL +
  304.     SWAP DROP 2 SWAP PUTI DROP
  305.     SWAP
  306.     3 GETI 3 ROLLD GETI 4 ROLL * 3 ROLLD GETI 4 ROLL +
  307.     SWAP DROP 2 SWAP PUTI DROP
  308.  
  309.     @ Multiply numerators and denominators
  310.     2 GETI 4 ROLLD GET 3 ROLLD
  311.     2 GETI 3 ROLLD GET
  312.     SWAP 4 ROLL * 3 ROLLD * \-> denom numer
  313.     \<<
  314.  
  315.     denom numer GCD
  316.     @ Reduce if non-zero GCD
  317.     DUP IF THEN
  318.          DUP
  319.          numer SWAP / 'numer' STO
  320.          denom SWAP / 'denom' STO
  321.        ELSE
  322.          DROP
  323.        END
  324.  
  325.     @ Convert from an improper fraction to a mixed number
  326.     numer denom / IP
  327.     numer denom MOD
  328.     denom
  329.  
  330.     @ Form the mixed number list
  331.     3 \->LIST
  332.  
  333.     \>> @ end of scope of denom and numer 
  334.  
  335.     @ DISPL the result
  336.     32 DISPL
  337.  
  338. @ Convert the list to three elements on the stack
  339. OBJ\-> DROP
  340.  
  341. END
  342. \>> 'MULTI' STO
  343.  
  344. \<< 
  345.  
  346. @ Convert elements on the stack to two lists.
  347. 3 \->LIST 4 ROLLD 3 \->LIST SWAP
  348.  
  349. @ Check that both denom's are non-zero.
  350. DUP2 3 GET SWAP 3 GET AND IF NOT 
  351. THEN
  352.    440 .5 BEEP
  353.    "DIVI: zero in denom" 1 DISP 1 FREEZE
  354. ELSE
  355.  
  356.     64 R\->B 131 R\->B BLANK PICT STO  @ Blank a 64X131 PICT
  357.  
  358.     @ Display the dividend
  359.     SWAP 5 DISPL SWAP 
  360.  
  361.     @ Now figure out where to place the divide sign
  362.     1 GETI SWAP DROP \->STR SIZE 3 + 6 * NEG 65 + R\->B
  363.     25 R\->B 2 \->LIST PICT SWAP
  364.     " / " 3 \->GROB
  365.     GOR
  366.  
  367.     @ And now the divisor
  368.     20 DISPL 
  369.     25 R\->B 35 R\->B 2 \->LIST
  370.     85 R\->B 35 R\->B 2 \->LIST LINE
  371.  
  372.     @ Multiply the two mixed numbers and DISPL the sum.
  373.  
  374.     @ Convert the two mixed numbers to improper fractions.
  375.     3 GETI 3 ROLLD GETI 4 ROLL * 3 ROLLD GETI 4 ROLL +
  376.     SWAP DROP 2 SWAP PUT
  377.     SWAP
  378.     3 GETI 3 ROLLD GETI 4 ROLL * 3 ROLLD GETI 4 ROLL +
  379.     SWAP DROP 2 SWAP PUT
  380.     SWAP
  381.  
  382.     @ Invert the quotient
  383.     3 GETI 3 ROLLD DROP 2 GETI PUT SWAP 2 SWAP PUT
  384.  
  385.     @ Multiply numerators and denominators
  386.     2 GETI 4 ROLLD GET 3 ROLLD
  387.     2 GETI 3 ROLLD GET
  388.     4 ROLL * 3 ROLLD * \-> denom numer
  389.     \<<
  390.  
  391.     denom numer GCD
  392.     @ Reduce if non-zero GCD
  393.     DUP IF THEN
  394.          DUP
  395.          numer SWAP / 'numer' STO
  396.          denom SWAP / 'denom' STO
  397.        ELSE
  398.          DROP
  399.        END
  400.  
  401.     @ Convert from an improper fraction to a mixed number
  402.     numer denom / IP
  403.     numer denom MOD
  404.     denom
  405.  
  406.     @ Form the mixed number list
  407.     3 \->LIST
  408.  
  409.     \>> @ end of scope of denom and numer 
  410.  
  411.     @ DISPL the result
  412.     37 DISPL
  413.  
  414. @ Convert the list to elements on the stack
  415. OBJ\-> DROP
  416.  
  417. END
  418. \>> 'DIVI' STO
  419.  
  420. @  Computes the lcm using the 
  421. @  lcm(m,n) * gcd(m,n) = m * n
  422.  
  423. \<< 
  424. DUP2 AND
  425.   IF    @ Check for 0 in the arguments.
  426.   THEN 
  427.      @  Compute m * n then the GCD and finally divide
  428.      DUP2 * 3 ROLLD GCD / 
  429.   ELSE 
  430.      @  Else return a zero
  431.      DROP2 0
  432.   END
  433. \>> 'LCM' STO
  434.  
  435.  
  436. @  This uses Euclid's algorithm to compute the gcd.
  437. @  Euclid's algorithm as Stan remembered it is:
  438. @  If you want the gcd of m and n, then iterate the following:
  439. @  First express  m as q0*n + r0
  440. @  then  express  n as q1*r0 +r1
  441. @  iterate        rn as q(n+2)*r(n+1) + r(n+2)
  442. @  when r(n+2) == 0 then r(n+1) is the gcd.
  443.  
  444. \<< 
  445. DUP2 AND     @ Check for a 0 in the arguments
  446.   IF
  447.   THEN
  448.     @ Apply Euclid's algorithm
  449.     DO DUP 3 ROLLD MOD DUP UNTIL NOT END DROP
  450.   ELSE 
  451.     @ Return a zero if a 0 was in the arguments.
  452.     DROP2 0  
  453.   END
  454. \>> 'GCD' STO
  455.  
  456.  
  457. \<< 
  458.  
  459. 0 DUP \-> row len midp           @ Grab the display row to use
  460.                                  @ and set up a couple locals
  461. \<<
  462.  
  463. @ First handle the whole number
  464. @ Display the whole number only if it is non-zero
  465. @ or the fraction is zero
  466. 1 GETI 3 ROLLD GETI SWAP DROP NOT 3 ROLL OR
  467. IF THEN
  468.   1 GETI \->STR 
  469.   DUP SIZE 'len' STO       @ save the length
  470.   3 \->GROB            @ Get the whole number to a GROB
  471.   PICT SWAP                          @ GOR it into the PICT
  472.   65 len 6 * - R\->B row 4 + R\->B 2 \->LIST 
  473.   SWAP GOR 
  474. ELSE 2 END
  475.  
  476. @ Now for the fraction part.
  477. @ First check the numerator.  If it's zero we're done.
  478. @ Otherwise ...
  479. @ computer the width of the fraction 
  480. GETI DUP IF THEN
  481.    \->STR SIZE 'len' STO
  482.    GETI \->STR SIZE len MAX 4 * 2 / 'midp' STO
  483.    DROP 2
  484.  
  485.    @ Now place the numerator in the PICT
  486.    GETI \->STR
  487.    DUP SIZE 'len' STO        @ Save the length
  488.    1 \->GROB PICT SWAP
  489.    len 2 * NEG midp +
  490.    66 + R\->B row R\->B 2 \->LIST
  491.    SWAP GOR
  492.      
  493.    @ Now the fraction bar
  494.    65 R\->B row 6 + R\->B 2 \->LIST
  495.    65 midp 2 * + R\->B row 6 + R\->B 2 \->LIST LINE
  496.         
  497.    @ Finally the denominator
  498.    GETI \->STR DUP SIZE 'len' STO
  499.    1 \->GROB
  500.    PICT SWAP
  501.    len 2 * NEG midp +
  502.    66 + R\->B row 8 + R\->B 2 \->LIST
  503.    SWAP GOR
  504. ELSE DROP END
  505.      
  506.     @ Display the result
  507.     0 R\->B DUP 2 \->LIST PVIEW 3 FREEZE
  508.     DROP                               @ DROP the GETI index
  509.   
  510. \>>  @ end scope of row and a couple locals
  511.  
  512. \>> 'DISPL' STO
  513.  
  514. @ Displays the 'fraction' on the top of the stack
  515. \<<
  516.   3 \->LIST DUP 3 GET
  517.   IF NOT
  518.      THEN
  519.           440 .5 BEEP "DISP: zero in denom"
  520.           1 DISP 1 FREEZE
  521.      ELSE 
  522.           64 R\->B 131 R\->B BLANK PICT STO
  523.           20 DISPL OBJ\-> DROP
  524.   END
  525. \>> 'DPLAY' STO
  526.  
  527.  
  528. \<< 
  529. 6 ROLL 6 ROLL 6 ROLL
  530. \>> 'SWAPR' STO
  531.  
  532. { S DPLAY 35.2
  533. SWAPR 36.2 DIVI
  534. 65.1 MULTI 75.1
  535. SUBTR 85.1 PLUS
  536. 95.1 } STOKEYS
  537.